  ________       __          ________                          ___ ___                __    
 /  _____/______|__| _____   \______ \ _____ __  _  ______    /   |   \  ____   ____ |  | __
/   \  __\_  __ \  |/     \   |    |  \\__  \\ \/ \/ /    \  /    ~    \/  _ \ /  _ \|  |/ /
\    \_\  \  | \/  |  | |  \  |    `   \/ __ \\     /   |  \ \    Y    (  <_> |  <_> )    < 
 \______  /__|  |__|__|_|  / /_______  (____  /\/\_/|___|  /  \___|_  / \____/ \____/|__|_ \
        \/               \/          \/     \/           \/         \/                    \/
    
    Grim Dawn Hook (c) 2015 atom0s [atom0s@live.com]

----------------------------------------------------------------------------------------------------

    The following documentation covers the usage and exposure of the HookCore object.
    
----------------------------------------------------------------------------------------------------

>> What is the HookCore?

    HookCore is the IHookCore object that is internally created inside of GDHook but passed to
    addons so they can interact with the main hook. This is the main object to use when you need
    to interact with the game and the GDHook itself.
    
    HookCore is automatically created for you inside of your addon, so there is no extra steps needed
    to make use of it. You can simply start using it immediately. 

----------------------------------------------------------------------------------------------------

>> Using HookCore

    Making use of HookCore is very simple and similar to other languages. HookCore is created from a
    class object inside of C++. This means that the calls are considered __thiscall. What this means
    is that the calling convention used (__thiscall) makes use of an object while making the call to
    the desired function. For example:
    
        class Derp
        {
        public:
            void HelloWorld();
        };
        
        auto x = new Derp();
        x->HelloWorld();
        delete x;
        
    This example C++ code shows creating a class called Derp, making an instance of it named 'x', and
    then invoking the 'HelloWorld' function. Because 'x' is an instance of Derp, we use the -> operator
    to invoke the function. In Lua -> is represented by : instead. 
    
    You can read more about the differences of . and : in Lua here:
        http://www.lua.org/pil/16.4.html
        http://lua-users.org/wiki/ColonForMethodCall
        
    In Lua, metatables are used to mimic a style of object-oriented coding. 
    
    Lets take for example, inside of the IHookCore interface, we have the function:
        virtual HWND GetHwnd(void) const = 0;
        
    In C++, this would be invoked like this:
        auto hWnd = coreObject->GetHwnd();
        
    In Lua, we can call this like:
        local hWnd = HookCore:GetHwnd();
        
    By using the : operator in Lua, we are automatically informing the interpreter that on the left side
    of the : (in this case HookCore) our object to invoke the GetHwnd with is HookCore. This can also
    be written like this:
        local hWnd = IHookCore.GetHwnd(HookCore);
        
    However in this case, it is not as elegant as the other.

----------------------------------------------------------------------------------------------------

>> What's Exposed To HookCore?
    
    The following functions inside of each interface are exposed to HookCore:
    
    You can find more info and the interface information inside of the plugin SDK at:
        \GDHook\Plugins\SDK\Plugin.h
    
        IHookCore
            GetInstallPath()
            GetHandle()
            GetHwnd()
            GetGameWidth()
            GetGameHeight()
            GetConfigManager()
            GetConsole()
            GetFontManager()
            GetInputManager()
            GetPluginManager()
            GetPointerManager()
            
        IConfigurationManager
            LoadConfiguration()
            LoadConfigurationEx()
            RemoveConfiguration()
            SaveConfiguration()
            GetConfigString()
            GetConfigBool()
            GetConfigInt()
            GetConfigUInt()
            GetConfigFloat()
            GetConfigDouble()
            
        IConsole
            Write()
            QueueCommand()
            RunTextScript()
            
        IFontManager
            CreateFontObject()
            GetFontObject()
            DeleteFontObject()
            GetHideObjects()
            SetHideObjects()
            
        IPrimitiveObject
            GetVisibility()
            GetPositionX()
            GetPositionY()
            GetWidth()
            GetHeight()
            GetColor()
            GetBorder()
            GetBorderColor()
            SetVisibility()
            SetPositionX()
            SetPositionY()
            SetWidth()
            SetHeight()
            SetColor()
            SetBorder()
            SetBorderColor()
            SetTextureFromFile()
                    ,
        IFontObject
            GetAlias()
            GetColor()
            GetFontName()
            GetFontHeight()
            GetPositionX()
            GetPositionY()
            GetLockPosition()
            GetText()
            GetVisibility()
            GetBold()
            GetItalic()
            GetRightJustified()
            GetAnchor()
            GetAnchorParent()
            GetAutoResize()
            GetParent()
            SetColor()
            SetFont()
            SetPosition()
            SetLockPosition()
            SetText()
            SetVisibility()
            SetBold()
            SetItalic()
            SetRightJustified()
            SetAnchor()
            SetAnchorParent()
            SetAutoResize()
            SetParent()
            GetBackground()
            
        IInputManager
            GetKeyboard()
            GetMouse()
            
        IKeyboard
            BindKey()
            UnbindKey()
            UnbindAllKeys()
            IsKeyBound()
            V2D()
            D2V()
            S2D()
            D2S()
            
        IMouse
            
        IPluginManager
            GetPluginCount()
            
        IPointerManager
            GetPointer()
        
    The following enumerations / constants are also exposed to Lua:
    
        FrameAnchor
            TopLeft
            TopRight
            BottomLeft
            BottomRight
            Right
            Bottom
            
        MouseInput
            LeftClick
            RightClick
            MiddleClick
            X1Click
            X2Click
            MouseWheelUp
            MouseWheelDown
            MouseMove
            
    The enumeration and constant values can be directly accessed like this inside of Lua:
        FrameAnchor.Right
        MouseInput.MouseMove
        
        And so on..
        

    PLEASE NOTE: Because of issues between C++ and Lua, some functions are not exposed. Some functions
    also have special cases, please read below for that information.
    
----------------------------------------------------------------------------------------------------

>> What Is Not Exposed To Lua?
    
    While Lua is powerful and has a lot of support and code bindings for other languages, it still does
    have its limitations. Because of that, not all of HookCore is exposed. Or some parts are exposed in
    a different manner.
    
    Here is a run down of which interfaces have things missing inside of Lua:
    
        IHookCore
            - Everything is exposed.
            
        IConfigurationManager
            - Everything is exposed.
            
        IConsole
            - Writef is not exposed because Lua cannot handle var_arg type functions. Use Lua's string.format instead.
            - HandleCommand is not exposed because Lua is not thread safe. Use QueueCommand instead.
            - ProcessCommand is not exposed because Lua is not thread safe. Use QueueCommand instead.
            
        IFontManager
            - Everything is exposed.
            
        IPrimitiveObject
            - SetTextureFromResource is not exposed because Lua addons cannot load modules.
                    ,
        IFontObject
            - GetMouseEventFunction is not exposed at all.
            - SetMouseEventFunction is not exposed normally. This is a special case.
            
                In order to use the SetMouseEventFunction, instead you can use the new global calls:
                    - AttachMouseEvent('font_obj_name');
                    - DetachMouseEvent('font_obj_name');
            
        IInputManager
            - Everything is exposed.
            
        IKeyboard
            - AddCallback and RemoveCallback are not exposed because of how they work.
            
        IMouse
            - Nothing to expose currently.
            
        IPluginManager
            - Because Lua is not thread safe, the various plugin functions are not exposed.
            
        IPointerManager
            - Everything is exposed.

----------------------------------------------------------------------------------------------------

>> Important Function Notes

    IConsole:QueueCommand does not wait for a return value. Instead this queues the command in the internal
    command task pool to be fired on the next tick. This allows addons to still invoke commands without having
    threading issues.
    
    IConsole:RunTextScript must be used with true as the first parameter from an addon! Failure to do so can
    crash the game or have unexpected results!
    
----------------------------------------------------------------------------------------------------

>> Example Usage

    Here are some examples of making use of the HookCore object to help get you started.
    
    To create a font object, we can do:
        local font = HookCore:GetFontManager():CreateFontObject('my_new_font_object');
        
    To check if a key is bound, we can do:
        -- Check if F1 is bound..
        local bound = HookCore:GetInputManager():GetKeyboard():IsKeyBound(0x3B, false, false, false, false, false);
        
    To write a formatted message to the console:
        HookCore:GetConsole():Write(string.format('Hello %s', 'world'))!;
        
